//
// Created by Administrator on 2021/5/7.
//

/*
每当用户执行变更文件夹操作时，LeetCode 文件系统都会保存一条日志记录。

下面给出对变更操作的说明：

"../" ：移动到当前文件夹的父文件夹。如果已经在主文件夹下，则 继续停留在当前文件夹 。
"./" ：继续停留在当前文件夹。
"x/" ：移动到名为 x 的子文件夹中。题目数据 保证总是存在文件夹 x 。
给你一个字符串列表 logs ，其中 logs[i] 是用户在 ith 步执行的操作。

文件系统启动时位于主文件夹，然后执行 logs 中的操作。

执行完所有变更文件夹操作后，请你找出 返回主文件夹所需的最小步数 。


示例 1：



输入：logs = ["d1/","d2/","../","d21/","./"]
输出：2
解释：执行 "../" 操作变更文件夹 2 次，即可回到主文件夹

        来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/crawler-log-folder
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/

#include <string>
#include <iostream>
#include <vector>
#include <stack>

using namespace std;

class Solution {
public:
    int minOperations(vector<string> &logs) {
        /**
         * name/ : 下跳到name子文件夹
         * ./ ：    保持在当前文件夹
         * ../：    回跳到父文件夹
         * 模拟整个过程，得到最后的文件夹深度
         */
        stack<string> logStack;
        logStack.push("main/");
        for (const auto &log:logs) {
            if (*(log.end() - 2) != '.') { // 跳到子文件夹
                logStack.push(logStack.top());
                logStack.top() += log;
            } else {
                if (log.size() == 2) continue; // ./ 保持当前文件夹不变
                else { // 回跳
                    if (logStack.size() > 1) logStack.pop();  // 最多只能回到main
                }
            }
        }
        return max((int) logStack.size() - 1, 0);
    }
};
class Solution2 { // 题解
public:
    int minOperations(vector<string>& logs) {
        // 并不需要真正做出栈
        int ans = 0;
        for(const string& log: logs){
            if(log == "../") ans = max(0, ans - 1);
            else if(log != "./") ans++;
        }
        return ans;
    }
};

int main() {
    vector<string> v{"d1/", "d2/", "../", "d21/", "./"};
    vector<string> v2{"d1/", "d2/", "./", "d3/", "../", "d31/"};
    vector<string> v3{"d1/", "../", "../", "../"};
    vector<string> v4{"./", "wz4/", "../", "mj2/", "../", "../", "ik0/", "il7/"};
    Solution2 sol;
    cout << sol.minOperations(v) << endl;
    cout << sol.minOperations(v2) << endl;
    cout << sol.minOperations(v3) << endl;
    cout << sol.minOperations(v4) << endl;
    return 0;
}